package hos.thread.hander

import android.os.Handler
import android.os.Looper
import android.util.Log
import hos.thread.RunnableThis
import hos.thread.ThreadOption

/**
 * <p>Title: SafeHandler </p>
 * <p>Description: 主线程 </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @date : 2023/8/4 19:14
 * @version : 1.0
 */
open class MainHandler protected constructor() : Handler(Looper.getMainLooper()) {

    companion object {

        @JvmStatic
        val handler by lazy {
            get()
        }

        @JvmStatic
        @Synchronized
        private fun get(): MainHandler {
            return MainHandler()
        }

        @JvmStatic
        @JvmOverloads
        inline fun run(
            handle: ThreadOption.UI = ThreadOption.UI.ON,
            time: Long = 400,
            crossinline block: MainHandler.() -> Unit,
        ) = handler.start(handle, time, block)

        @JvmStatic
        fun isMainThread(): Boolean {
            return Looper.getMainLooper().thread === Thread.currentThread()
        }

    }

    /**
     * 切换到主线程
     *
     * @param runnable 主线程
     */
    fun postToMain(runnable: RunnableThis): MainHandler {
        post(runnable)
        return this
    }

    /**
     * 在主线程上运行
     *
     * @param runnable 主线程
     */
    fun postOnMain(runnable: RunnableThis): MainHandler {
        if (isMainThread()) {
            runnable.run()
        } else {
            postToMain(runnable)
        }
        return this
    }

    /**
     * 切换到主线程
     *
     * @param runnable 主线程
     */
    inline fun postToMain(crossinline block: MainHandler.() -> Unit): MainHandler {
        postToMain(RunnableThis {
            try {
                block.invoke(this)
            } finally {
                removeCallbacks(it)
                Log.d("Thread", "removeCallbacks")
            }
        })
        return this
    }

    /**
     * 在主线程上运行
     *
     * @param runnable 主线程
     */
    inline fun postOnMain(crossinline block: MainHandler.() -> Unit): MainHandler {
        if (isMainThread()) {
            block.invoke(this)
        } else {
            postToMain(block)
        }
        return this
    }

    fun clearCallback() {
        removeCallbacksAndMessages(null)
    }

    fun remove(runnable: Runnable) {
        removeCallbacks(runnable)
    }

    @JvmOverloads
    inline fun start(
        handle: ThreadOption.UI = ThreadOption.UI.ON,
        time: Long = 300,
        crossinline block: MainHandler.() -> Unit,
    ): MainHandler {
        if (handle == ThreadOption.UI.TO) {
            return postToMain(block)
        }
        if (handle == ThreadOption.UI.DELAYED) {
            postDelayed(RunnableThis {
                try {
                    block.invoke(this)
                } finally {
                    removeCallbacks(it)
                    Log.d("Thread: ", "removeCallbacks")
                }
            }, time)
            return this
        }
        if (handle == ThreadOption.UI.TIME) {
            postAtTime(RunnableThis {
                try {
                    block.invoke(this)
                } finally {
                    removeCallbacks(it)
                    Log.d("Thread: ", "removeCallbacks")
                }
            }, time)
            return this
        }
        return postOnMain(block)
    }
}